package com.weareint.feigncopy;

import com.github.benmanes.caffeine.cache.Cache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 *
 *
 * <pre>
 * 使用Caffeine实现 AbsCacheMappingFeignDataService
 * </pre>
 *
 * @author johnny
 * @date 2021-07-26 10:07 上午
 */
@Slf4j
public abstract class AbsCaffeineCacheMappingFeignDataService<S, D, T>
        extends AbsCacheMappingFeignDataService<S, D, T> {

    public static String appNamePrefix;
    /**
     * Caffeine Cache
     *
     * @return
     */
    public abstract Cache<String, D> caffeineCache();

    @Override
    public List<D> fromCache(CacheTimeContext timeContext) {
        if (CollectionUtils.isEmpty(data())) {
            return null;
        }
        List<D> allList = new ArrayList<>();
        Set<String> keys = cacheKey();
        List<String> expireKeys = new ArrayList<>();
        List<String> existKeys = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(keys)) {
            keys.forEach(
                    key -> {
                        D dCache = caffeineCache().getIfPresent(key);
                        if (dCache != null) {
                            allList.add(dCache);
                            existKeys.add(key);
                        } else {
                            expireKeys.add(key);
                        }
                    });
            // 存在的key
            if (CollectionUtils.isNotEmpty(existKeys)) {
                if (log.isDebugEnabled()) {
                    log.debug("【feign mapping caffeineKeys : {} caffeineDs：{}】", existKeys, allList);
                }
            }
            // 过期key 走接口
            cacheFeignData(expireKeys, (key, d) -> caffeineCache().put(key, d));
        }
        if (log.isDebugEnabled()) {
            log.debug("【feign mapping allList : {}】", allList);
        }
        return allList;
    }
}
